package networks.event;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;

public class EventDispatcher {

    private HashMap<String, List<Event>> _eventCallbackMap;

    public boolean AddEventListener(String type, Event callback) {
        if (callback == null) {
            return false;
        }

        if (_eventCallbackMap == null) {
            _eventCallbackMap = new HashMap<String, List<Event>>();
        }

        if (_eventCallbackMap.containsKey(type)) {
            _eventCallbackMap.get(type).add(callback);
        } else {
            List<Event> list = new ArrayList<Event>();
            list.add(callback);
            _eventCallbackMap.put(type, list);
        }

        return true;
    }

    public boolean RemoveEventListener(String type, Event callback) {
        if (callback == null) {
            return false;
        }

        if (_eventCallbackMap == null) {
            return false;
        }

        if (_eventCallbackMap.containsKey(type)) {
            _eventCallbackMap.get(type).remove(callback);
            return true;
        }
        return false;
    }

    public boolean RemoveEventListener(String type) {
        if (_eventCallbackMap == null) {
            return false;
        }

        if (_eventCallbackMap.containsKey(type)) {
            _eventCallbackMap.remove(type);
            return true;
        }
        return false;
    }

    public void RemoveAll() {
        if (_eventCallbackMap != null)
            _eventCallbackMap.clear();
    }

    public boolean BroadcastEvent(String type, EventData eventData) {
        if (_eventCallbackMap == null) {
            return false;
        }

        if (_eventCallbackMap.containsKey(type)) {
            List<Event> events = _eventCallbackMap.get(type);
            if (events != null) {
                for (Event event : events) {
                    event.Invoke(eventData);
                }
                return true;
            }
            return false;
        }
        return false;
    }

    public boolean BroadcastEvent(EventData eventData) {
        if (_eventCallbackMap == null) {
            return false;
        }

        if (eventData == null) {
            return false;
        }

        String type = eventData.getType();
        if (_eventCallbackMap.containsKey(type)) {
            List<Event> events = _eventCallbackMap.get(type);
            if (events != null) {
                for (Event event : events) {
                    event.Invoke(eventData);
                }
                return true;
            }
            return false;
        }
        return false;
    }

    public boolean HasEventListener(String type) {
        if (_eventCallbackMap == null) {
            return false;
        }

        if (_eventCallbackMap.containsKey(type)) {
            return true;
        }
        return false;
    }

    public boolean HasEventListener(String type, Event callback) {
        if (callback == null) {
            return false;
        }

        if (_eventCallbackMap == null) {
            return false;
        }

        if (_eventCallbackMap.containsKey(type)) {
            List<Event> events = _eventCallbackMap.get(type);
            return events.contains(callback);
        }
        return false;
    }

    public void Destory() {
        RemoveAll();
        _eventCallbackMap = null;
    }
}
